package com.sy.olddriver.utils;

import com.sy.olddriver.exception.OldDriverException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 对Apache中的QueryRunner进行二次封装
 * 提供更简洁的操作方法
 *
 * @author Administrator
 */
public class JdbcHelper {
    private static QueryRunner runner = new QueryRunner();

    private JdbcHelper() {

    }


    /**
     * 查询单个JavaBean对象
     *
     * @param sql    要执行的SQL语句
     * @param clazz  JavaBean的数据类型
     * @param params 占位符参数对应的值
     * @param <T>    泛型参数
     * @return 查询到的单个JavaBean对象
     * @author Administrator
     */
    public static <T> T queryForBean(String sql, Class<T> clazz, Object... params) {
        return queryForBean(false, sql, clazz, params);
    }

    public static <T> T queryForBean(boolean needClose, String sql, Class<T> clazz, Object... params) {
        Connection con = null;
        try {
            con = DbUtils.getConnection();
            return runner.query(con, sql, new BeanHandler<>(clazz), params);
        } catch (Exception e) {
            e.printStackTrace();
            //对于Dao层出现的异常可以包转成业务异常继续上抛
            //否则如果Dao层有问题，则Serivce无法获得异常
            //对于用户而言就会隐藏这个异常
            throw new OldDriverException("服务器出现了异常");
        } finally {
            if (null != con && needClose) {
                DbUtils.close();
            }
        }
    }


    /**
     * 查询JavaBean对象列表
     *
     * @param sql    要执行的SQL语句
     * @param clazz  JavaBean的数据类型
     * @param params 占位符参数对应的值
     * @param <T>    泛型参数
     * @return 查询到的JavaBean列表对象
     * @author Administrator
     */
    public static <T> List<T> queryForBeanList(String sql, Class<T> clazz, Object... params) {
        return queryForBeanList(false, sql, clazz, params);
    }

    public static <T> List<T> queryForBeanList(boolean needClose, String sql, Class<T> clazz, Object... params) {
        Connection con = null;
        try {
            con = DbUtils.getConnection();
            return runner.query(con, sql, new BeanListHandler<>(clazz), params);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("服务器出现了异常");
        } finally {
            if (null != con && needClose) {
                DbUtils.close();
            }
        }
    }

    /**
     * DML操作
     *
     * @param sql    要执行的SQL语句
     * @param params 占位符参数的值
     * @return 是否操作成功
     * @author Administrator
     */
    public static boolean update(String sql, Object... params) {
        return update(true, sql, params);
    }

    /**
     * DML操作
     *
     * @param needClose 是否需要关闭连接对象
     * @param sql       要执行的SQL语句
     * @param params    占位符参数的值
     * @return 是否操作成功
     * @author Administrator
     */
    public static boolean update(boolean needClose, String sql, Object... params) {
        Connection con = null;
        try {
            con = DbUtils.getConnection();
            return runner.update(con, sql, params) > 0;
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("服务器出现了异常");
        } finally {
            if (null != con && needClose) {
                DbUtils.close();
            }
        }
    }


    /**
     * 标量查询
     *
     * @param sql    要执行的SQL语句
     * @param params 占位符参数对应的值
     * @param <T>    泛型参数
     * @return 查询到的标量的值
     * @author Administrator
     */
    public static <T> T queryForScalar(String sql, Object... params) {
        return queryForScalar(false, sql, params);
    }

    public static <T> T queryForScalar(boolean needClose, String sql, Object... params) {
        Connection con = null;
        try {
            con = DbUtils.getConnection();
            return runner.query(con, sql, new ScalarHandler<>(), params);
        } catch (Exception e) {
            e.printStackTrace();
            throw new OldDriverException("服务器出现了异常");
        } finally {
            if (null != con && needClose) {
                DbUtils.close();
            }
        }
    }
}
